package com.kobeliu.entity;

/**
 * @Author: Kobe_Liu
 * @Date: 2021/12/9 10:10
 */

/**
 * 中等题 但是其实就是题目难懂 没啥难度
 *
 * 给你一个字符串数组 board 表示井字游戏的棋盘。当且仅当在井字游戏过程中，棋盘有可能达到 board 所显示的状态时，才返回 true 。
 *
 * 井字游戏的棋盘是一个 3 x 3 数组，由字符 ' '，'X' 和 'O' 组成。字符 ' ' 代表一个空位。
 *
 * 以下是井字游戏的规则：
 *
 *     玩家轮流将字符放入空位（' '）中。
 *     玩家 1 总是放字符 'X' ，而玩家 2 总是放字符 'O' 。
 *     'X' 和 'O' 只允许放置在空位中，不允许对已放有字符的位置进行填充。
 *     当有 3 个相同（且非空）的字符填充任何行、列或对角线时，游戏结束。
 *     当所有位置非空时，也算为游戏结束。
 *     如果游戏结束，玩家不允许再放置字符。
 */
public class Demo_74_No794 {

    public boolean validTicTacToe(String[] board) {
        int num_X = 0,num_O = 0,num = 0;
        char[][] chars = new char[3][3];
        char c;
        int len = board.length;
        for(int i=0;i<len;i++){
            int j = 0;
            while(j<3){
                c = board[i].charAt(j);
                if(c=='X') num_X++;
                if(c=='O') num_O++;
                else num++;
                chars[i][j] = c;
                j++;
            }
        }
        if(num_O > num_X || num_X-num_O>1) return false;
        //要讨论的是x成立的情况
        boolean x = check(chars,'X');
        boolean o = check(chars,'O');
        //都赢就是错的
        if(x&&o) return false;
        //如果x赢了
        if(x && (num_X-num_O==1)) return  true;
        //如果o赢了
        if(o && num_O==num_X) return true;
        if(!o && !x) return true;
        return false;
    }

    boolean check(char[][] chars,char c){
        for(int i=0;i<chars.length;i++){
            //行相等
            if(chars[i][0]==c && chars[i][1]==c && chars[i][2]==c){
                return true;
            }
        }
        for(int i=0;i<chars[0].length;i++){
            //列相等
            if(chars[0][i]==c && chars[1][i]==c && chars[2][i]==c){
                return true;
            }
        }
        //两条对角线
        if(chars[0][0]==c && chars[1][1]==c && chars[2][2]==c){
            return true;
        }
        if(chars[0][2]==c && chars[1][1]==c && chars[2][0]==c){
            return true;
        }
        return false;
    }
}
